#include "WordTranslator.h"
#include <QTimer>
#include <QTextCodec>
#include <QStringList>
#include <QSettings>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QDebug>

static const QString appName = QString("wordTranslator");
static const QString configFileName = QString("config");

/// Method to read the config file
bool readConfigFile(QIODevice &device, QSettings::SettingsMap &map)
{
	QXmlStreamReader xmlReader(&device);
	QStringList elements; // Elements list

	// While we don't reach the end of the XML
	while ( !xmlReader.atEnd() && !xmlReader.hasError() ) {
		xmlReader.readNext(); // Read the next token
		// If token type is "StartElement" and its name different from "Settings"
		if ( xmlReader.isStartElement() && (xmlReader.name() != "Settings") ) {
			// We add the element to the QStringList
			elements.append(xmlReader.name().toString());
		} else if ( xmlReader.isEndElement() ) { // If token type is "EndElement"
			// Delete the last element
			if (!elements.isEmpty())
				elements.removeLast();
		} else if (xmlReader.isCharacters() && !xmlReader.isWhitespace()) { // If token contains a value
			// Key to use with the QSettings map
			QString key;
			// Populate key with the list of elements
			for (int i=0; i<elements.size(); ++i) {
				// Separate elements with '/'
				if (i!=0)
					key += "/";
				key += elements.at(i);
			}
			// Add value to the QSettings map
			map[key] = xmlReader.text().toString();
		}
	}
	// If we have any error, warn about it
	if (xmlReader.hasError()) {
		qWarning() << xmlReader.errorString();
		return false;
	}
	return true;
}

/// Method to write the config file
bool writeConfigFile(QIODevice &device, const QSettings::SettingsMap &map)
{
	QXmlStreamWriter xmlWriter(&device);

	xmlWriter.setAutoFormatting(true);
	xmlWriter.writeStartDocument();
	xmlWriter.writeStartElement("Settings");

	QStringList prev_elements;
	QSettings::SettingsMap::ConstIterator it; // Iterator of QSettings map
	// Iterate over the QSettings map
	for (it = map.begin(); it != map.end(); it++) {
		// Split the key with its separator to get the elements
		QStringList elements = it.key().split("/");
		int x = 0;
		// Identify elements to be closed
		while ( (x < prev_elements.size()) && (elements.at(x) == prev_elements.at(x)) ) {
			x++;
		}
		for (int i=(prev_elements.size() - 1); i>=x; i--) {
			xmlWriter.writeEndElement();
		}
		for (int i=x; i<elements.size(); i++) {
			xmlWriter.writeStartElement(elements.at(i));
		}
		// Write the element value
		xmlWriter.writeCharacters(it.value().toString());
		prev_elements = elements;
	}
	for(int i = 0; i < prev_elements.size(); i++) {
		xmlWriter.writeEndElement();
	}
	// Close the "Settings" element and the document
	xmlWriter.writeEndElement();
	xmlWriter.writeEndDocument();
	return true;
}

int main(int argc, char *argv[])
{
    //QObject::connect(&hello, SIGNAL(done()), &app, SLOT(quit()));

	QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

	// Registration of our storage format for the configuration file (in XML)
	const QSettings::Format xmlFormat = QSettings::registerFormat("xml", readConfigFile, writeConfigFile);
	// We create the QSettings object using our own format. It'll be storaged in $HOME/.config/appName/configFileName.conf
	QSettings settings(xmlFormat, QSettings::UserScope, appName, configFileName);


	WordTranslator app(argc, argv, &settings);
    QTimer::singleShot(100, &app, SLOT(world()));
    return app.exec();
}

